package cn.z2huo.knowledge.concurrency.lock.reentrantlock.dead;

import cn.hutool.core.thread.ThreadUtil;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 *
 * @author z2huo
 */
class TwoLockDeadTest {

    public static final ThreadMXBean MX_BEAN = ManagementFactory.getThreadMXBean();

    public static void main(String[] args) {

        Lock lock = new ReentrantLock();
        Lock lock2 = new ReentrantLock();

        Runnable runnable = () -> TwoLockDeadDemo.twolockInterruptiblyLock(lock, lock2);
        Runnable runnable2 = () -> TwoLockDeadDemo.twolockInterruptiblyLock(lock2, lock);

        Thread thread = new Thread(runnable, "thread-1");
        Thread thread2 = new Thread(runnable2, "thread-2");

        System.out.println(thread.getId());
        System.out.println(thread2.getId());
        System.out.println();

        thread.start();
        thread2.start();

        ThreadUtil.sleep(2000);
        System.out.println();

        long[] deadlockedThreads = MX_BEAN.findDeadlockedThreads();
        if (deadlockedThreads != null && deadlockedThreads.length > 0) {
            System.out.println("dead lock");
            System.out.println();
            for (long pid : deadlockedThreads) {

                // 获取不带有堆栈跟踪信息的线程数据
                ThreadInfo threadInfo = MX_BEAN.getThreadInfo(pid);
                // 获取带有堆栈跟踪信息的线程数据
//                ThreadInfo threadInfo = MX_BEAN.getThreadInfo(pid, Integer.MAX_VALUE);

                System.out.println(threadInfo);
            }

            // 中断两个死锁线程中的一个线程，解除死锁状态
            System.out.println("中断两个死锁线程中的一个线程");
            thread.interrupt();
        }

    }

}
